package com.jolink.omiis.wechat.api;

import java.util.Arrays;

import org.apache.commons.lang.ArrayUtils;
import org.junit.Assert;
import org.slf4j.LoggerFactory;

import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.JsonArray;
import com.google.gson.JsonObject;
import com.jolink.omiis.wechat.message.type.MessageType;
import com.jolink.omiis.wechat.util.GsonUtil;

/**
 * 客服消息构造器
 * 
 * @author WangYanqing
 *
 */
public class CSMessageBuilder {
	private static org.slf4j.Logger logger = LoggerFactory.getLogger(CSMessageBuilder.class);

	/**
	 * 创建消息 IMAGE、VOICE(AUDIO)、VIDEO、MUSIC、NEWS、TEXT
	 * 
	 * @param toUser
	 * @param msgType
	 * @param values
	 * @return
	 */
	public static String createMessage(String toUser, String msgType, String... values) {
		Assert.assertNotEquals("toUser为空！", toUser);
		if (values == null || values.length <= 0) {
			Assert.assertTrue("发送客服消息内容为空！", false);
		}
		MessageType mt = MessageType.valueOf(msgType.toUpperCase());
		logger.info("创建微信客服消息，toUser：{}，msgType：{}，values：{}。", toUser, mt.getValue(), Arrays.toString(values));
		int size = values.length;
		String message = "";
		switch (mt) {
		case TEXT:
			assertSize(1, size);
			message = CSMessageBuilder.createTextMessage(toUser, values[0]);
			break;
		case IMAGE:
			assertSize(1, size);
			message = CSMessageBuilder.createImagetMessage(toUser, values[0]);
			break;
		case VOICE:
			assertSize(1, size);
			message = CSMessageBuilder.createVoiceMessage(toUser, values[0]);
			break;
		case VIDEO:
			assertSize(4, size);
			message = CSMessageBuilder.createVideoMessage(toUser, values[0], values[1], values[2], values[3]);
			break;
		case NEWS:
			message = CSMessageBuilder.createNewsMessage(toUser, values);
			break;
		case MUSIC:
			assertSize(5, size);
			message = CSMessageBuilder.createMusicMessage(toUser, values[0], values[1], values[2], values[3],
					values[4]);
			break;
		default:
			throw new RuntimeException("不支持的消息类型！");
		}

		return message;
	}

	private static String createTextMessage(String toUser, String content) {
		logger.info("创建文本消息：toUser：{}，content：{}。", toUser, content);
		String msgType = MessageType.TEXT.getValue();
		Gson gson = new GsonBuilder().disableHtmlEscaping().create();
		JsonObject message = new JsonObject();
		message.addProperty("touser", toUser);
		message.addProperty("msgtype", msgType);
		JsonObject text = new JsonObject();
		text.addProperty("content", content);
		message.add("text", text);
		return GsonUtil.jsonElement2Json(message);
	}

	private static String createImagetMessage(String toUser, String mediaId) {
		logger.info("创建图片消息：toUser：{}，mediaId：{}。", toUser, mediaId);
		String msgType = MessageType.IMAGE.getValue();
		JsonObject message = new JsonObject();
		message.addProperty("touser", toUser);
		message.addProperty("msgtype", msgType);
		JsonObject image = new JsonObject();
		image.addProperty("media_id", mediaId);
		message.add("image", image);
		return GsonUtil.jsonElement2Json(message);
	}

	private static void assertSize(int limit, int size) {
		if (size < limit) {
			throw new RuntimeException("参数不合法，实际值=" + size + "，预期值=" + limit);
		}
	}

	private static String createVideoMessage(String toUser, String mediaId, String thumbMediaId, String title,
			String description) {
		logger.info("创建视频消息：toUser：{}，mediaId：{}，thumbMediaId：{}，title：{}，description：{}。", toUser, mediaId,
				thumbMediaId, title, description);
		String msgType = MessageType.VIDEO.getValue();
		JsonObject message = new JsonObject();
		message.addProperty("touser", toUser);
		message.addProperty("msgtype", msgType);
		JsonObject video = new JsonObject();
		video.addProperty("media_id", mediaId);
		video.addProperty("thumb_media_id", thumbMediaId);
		video.addProperty("title", title);
		video.addProperty("description", description);
		message.add("video", video);
		return GsonUtil.jsonElement2Json(message);
	}

	private static String createVoiceMessage(String toUser, String mediaId) {
		logger.info("创建音频消息：toUser：{}，mediaId：{}。", toUser, mediaId);
		String msgType = MessageType.VOICE.getValue();
		JsonObject message = new JsonObject();
		message.addProperty("touser", toUser);
		message.addProperty("msgtype", msgType);
		JsonObject voice = new JsonObject();
		voice.addProperty("media_id", mediaId);
		message.add("voice", voice);
		return GsonUtil.jsonElement2Json(message);
	}

	private static String createMusicMessage(String toUser, String title, String description, String musicUrl,
			String hqMusicUrl, String thumbMediaId) {
		logger.info("创建音频-MP3格式消息：toUser：{}，title：{}，descrption：{}，musicUrl：{}，hqMusicUrl：{}，thumbMediaId：{}。", toUser, title,
				description, musicUrl, hqMusicUrl, thumbMediaId);
		String msgType = MessageType.MUSIC.getValue();
		JsonObject message = new JsonObject();
		message.addProperty("touser", toUser);
		message.addProperty("msgtype", msgType);
		JsonObject music = new JsonObject();
		music.addProperty("title", title);
		music.addProperty("description", description);
		music.addProperty("musicurl", musicUrl);
		music.addProperty("hqmusicurl", hqMusicUrl);
		music.addProperty("thumb_media_id", thumbMediaId);
		message.add("music", music);
		return GsonUtil.jsonElement2Json(message);
	}

	private static String createNewsMessage(String toUser, String[] values) {
		int limit = 8;
		int itemSize = values.length / 4;
		if (itemSize > limit) {
			logger.warn("图文消息超过阀值：{}条，超过条数将被忽略。", limit);
		}
		logger.info("创建图文消息：toUser：{}，news：{}。", toUser, Arrays.toString(values));
		String msgType = MessageType.NEWS.getValue();
		JsonObject message = new JsonObject();
		message.addProperty("touser", toUser);
		message.addProperty("msgtype", msgType);
		JsonObject news = new JsonObject();
		JsonArray articles = new JsonArray();
		for (int i = 0; i < values.length;) {
			logger.info("添加第{}条图文消息，{}。", (i + 1), ArrayUtils.subarray(values, i, i + 4));
			JsonObject entry = new JsonObject();
			entry.addProperty("title", values[i]);
			entry.addProperty("descrption", values[i + 1]);
			entry.addProperty("url", values[i + 2]);
			entry.addProperty("picurl", values[i + 3]);
			articles.add(entry);
			i += 4;
		}
		news.add("articles", articles);
		message.add("news", news);
		return GsonUtil.jsonElement2Json(message);
	}
}
